# -*- coding: utf-8 -*-
# @File     : services.py
# @Author   : bingjia
# @Time     : 2020/8/4 13:38
# @Desc     : 提供auth模块的服务接口

from django.db.models import Q
from django.db import IntegrityError
from django.contrib.auth import get_user_model
from django.utils.translation import ugettext as _

from ..base.api import exceptions as exc
from ..users.serializers import UserSerializer
from ..base.utils.tokens import get_token_for_user

from . import signals


def make_auth_response_data(user) -> dict:
    """
    添加token并返回用户数据
    """
    serializer = UserSerializer(user)
    data = dict(serializer.data)
    data["token"] = get_token_for_user(user, "authentication")
    return data


def get_user_by_username_or_email(username_or_email):
    """
    通过用户名或者邮箱获取用户
    """
    user_model = get_user_model()
    qs = user_model.objects.filter(Q(username__iexact=username_or_email) |
                                   Q(email__iexact=username_or_email))

    if len(qs) > 1:
        qs = qs.filter(Q(username=username_or_email) |
                       Q(email=username_or_email))

    if len(qs) == 0:
        raise exc.ValidationError(_("Username or password does not matches user."))

    user = qs[0]
    return user


def get_and_validate_user(*, username: str, password: str) -> bool:
    """
    验证用户名和密码
    """

    user = get_user_by_username_or_email(username)
    if not user.check_password(password):
        raise exc.ValidationError(_("Username or password does not matches user."))
    return user


def is_user_already_registered(*, username: str, email: str) -> (bool, str):
    """
    通过用户名 和 邮件 检测用户是否注册
    """

    user_model = get_user_model()
    if user_model.objects.filter(username=username):
        return (True, _("Username is already in use."))

    if user_model.objects.filter(email=email):
        return (True, _("Email is already in use."))

    return (False, None)


def user_register(username: str, password: str, email: str, full_name: str):
    """
    检测是否注册，并完成注册
    """
    is_registered, reason = is_user_already_registered(username=username, email=email)
    if is_registered:
        raise exc.ValidationError(reason)

    user_model = get_user_model()
    user = user_model(username=username,
                      email=email,
                      full_name=full_name,
                      read_new_terms=True)
    user.set_password(password)
    try:
        user.save()
    except IntegrityError:
        raise exc.ValidationError(_("User is already registered."))

    signals.user_registered_signal.send(sender=user.__class__, user=user)
    return user
